/*

This file is part of roomyak.

Copyright (C) 2008 Pixecur Technologies Incorporated (Esotera).
Visit Esotera at http://www.esoteras3.com
 
roomyak is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
roomyak is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with roomyak; see the file COPYING.  If not, write to 
Pixecur Technologies, 213-31 Peet Street, St. John's, NL, A1B 3W8. 
 
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
 
*/

package com.datasentinel.util.thumbnail;

import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

/**
 * @author rickp
 * 
 */
public class FileThumbnailer implements ThumbnailProvider
{
	private static Logger logger = Logger.getLogger(FileThumbnailer.class
			.getName());
	private static final String THUMBNAIL_PROVDER_CLASS = "com.datasentinel.util.thumbnail.provider";
	private static FileThumbnailer instance;
	private ThumbnailProvider thumbnailProvider;
	private ThumbnailProvider defaultThumbnailProvider;
	
	private Image unknown128x128 = null;
	private Image unknown64x64 = null;

	public static synchronized FileThumbnailer getInstance()
	{
		if (!(instance instanceof FileThumbnailer))
		{
			instance = new FileThumbnailer();
		}
		return instance;
	}
	
	private Image getThumbnail(ThumbnailProvider provider,File file,boolean large) throws ThumbnailException
	{
		return large ? provider.getThumbnail(file) : provider.getSmallThumbnail(file);
	}
	
	private Image getThumbnail(File file,boolean large) throws ThumbnailException
	{
		Image thumbnail = null;
		
		if(!file.exists())
			throw new ThumbnailException("file does not exist: "+file);
		
		if(!file.toURI().toString().startsWith("file:"))
		{
			throw new ThumbnailException("cannot thumbnail not native file!"+file);
		}
		
		
		
		try
		{
			if(thumbnailProvider instanceof ThumbnailProvider)
			{
				logger.fine("USING CUSTOM THUMBNAILER: getting thumbnail image for file "+file);
				thumbnail = getThumbnail(thumbnailProvider,file,large);
			}
		}
		catch(ThumbnailException te)
		{
			logger.log(Level.FINE, "error from configured thumbnail provider", te);
		}
		
		if(thumbnail == null)
		{
			try
			{
				logger.fine("USING DEFAULT THUMBNAILER: getting thumbnail image for file "+file);
				thumbnail = getThumbnail(defaultThumbnailProvider,file,large);
			}
			catch(ThumbnailException te2)
			{
				logger.log(Level.FINE, "error from default thumbnail provider", te2);
				thumbnail = large ? unknown128x128 : unknown64x64;
			}
		}
		
		if(thumbnail == null)
		{
			throw new ThumbnailException("could not load thumbnail for "+file);
		}
		return thumbnail;
	}
	
	@Override
	public Image getSmallThumbnail(File file) throws ThumbnailException
	{
		return getThumbnail(file,false);
	}
	
	@Override
	public Image getThumbnail(File file) throws ThumbnailException
	{
		return getThumbnail(file,true);
	}
	
	private void configureThumbnailProvider()
	{
		defaultThumbnailProvider = new DefaultThumbnailProvider();
		String customProviderStr = System.getProperty(THUMBNAIL_PROVDER_CLASS);
		
		if(customProviderStr == null)
		{
			// try to set based on File separator
			// of course, there will eventually be more providers, for now this
			// should remove some runtime config burden
			if("\\".equals(File.separator))
			{
				customProviderStr = "com.datasentinel.util.win32.Win32Thumbnailer";
			}
			else if(!System.getProperty("os.name").toLowerCase().startsWith("mac"))
			{
				customProviderStr = "com.datasentinel.util.gnome.GTKThumbnailer";
			}
		}
		
		
		if (customProviderStr instanceof String)
		{
			try
			{
				logger.config("custom file thumbnailer requested: "
						+ customProviderStr);
				Class<?> thumbnailProviderClass = Class
						.forName(customProviderStr);
				Object newInstance = thumbnailProviderClass.newInstance();
				if (newInstance instanceof ThumbnailProvider)
				{
					thumbnailProvider = (ThumbnailProvider)newInstance;
					logger
							.info("custom file thumbnailer successfully configured as: "
									+ customProviderStr);
				}
			}
			catch (Exception e)
			{
				logger.log(Level.WARNING,
						"trouble loading custom file thumbnailer: "
								+ customProviderStr, e);
			}
		}
		else
		{
			logger.warning("no file thumbnailer configured.");
		}
	}
	
	private void loadResources()
	{
		try
		{
			unknown128x128 = ImageIO.read(getClass().getResource("unknown128x128.png"));
			unknown64x64 = ImageIO.read(getClass().getResource("unknown64x64.png"));
		}
		catch(IOException ioe)
		{
			logger.log(Level.WARNING, "Error loading icon resource", ioe);
		}
	}
	
	private FileThumbnailer()
	{
		super();
		loadResources();
		configureThumbnailProvider();
	}
}
